package algorithm

import (
	"b2c-delivery-optimization/internal/model"
	"fmt"
	"math/rand"
	"time"
)

// TimeSeriesAnalyzer 时序分析器
type TimeSeriesAnalyzer struct {
	// 历史数据
	HistoricalData []*model.Order
	// 时间窗口
	TimeWindow time.Duration
	// LSTM预测器
	lstmPredictor *LSTMPredictor
}

// OrderPattern 订单模式
type OrderPattern struct {
	TimeSlot      time.Time
	OrderCount    int
	AverageVolume float64
	PopularAreas  []string
	PeakHours     []int
}

// NewTimeSeriesAnalyzer 创建新的时序分析器
func NewTimeSeriesAnalyzer(historicalData []*model.Order, timeWindow time.Duration) *TimeSeriesAnalyzer {
	analyzer := &TimeSeriesAnalyzer{
		HistoricalData: historicalData,
		TimeWindow:     timeWindow,
	}
	// 初始化LSTM预测器
	analyzer.lstmPredictor = NewLSTMPredictor(64, 24, 12)
	return analyzer
}

// AnalyzePatterns 分析订单模式
func (a *TimeSeriesAnalyzer) AnalyzePatterns() []*OrderPattern {
	// 首先计算高峰时段
	peakHours := a.FindPeakHours()
	// 然后生成每个时段的模式
	patterns := make([]*OrderPattern, 0)
	for i := 0; i < 24; i++ {
		timeSlot := time.Now().Add(time.Duration(i) * time.Hour)
		prediction := a.lstmPredictor.Predict(timeSlot)
		pattern := &OrderPattern{
			TimeSlot:      timeSlot,
			OrderCount:    int(prediction),
			AverageVolume: a.calculateAverageVolume(timeSlot),
			PopularAreas:  a.getPopularAreas(timeSlot),
			PeakHours:     peakHours, // 使用预先计算的高峰时段
		}
		patterns = append(patterns, pattern)
	}
	return patterns
}

// PredictFutureOrders 预测未来订单数量
func (a *TimeSeriesAnalyzer) PredictFutureOrders(hours int) ([]int, []float64) {
	predictions := make([]int, hours)
	errors := make([]float64, hours)
	for i := 0; i < hours; i++ {
		prediction := a.lstmPredictor.Predict(time.Now().Add(time.Duration(i) * time.Hour))
		predictions[i] = int(prediction)
		errors[i] = 0.1 * prediction // 设置预测误差为预测值的10%
	}
	return predictions, errors
}

// generateOrder 生成订单
func (a *TimeSeriesAnalyzer) generateOrder(orderTime time.Time, action string) *model.Order {
	// 生成随机的配送站ID
	stationID := fmt.Sprintf("STATION_%d", rand.Intn(5))
	return &model.Order{
		ID:                fmt.Sprintf("ORD_%d", time.Now().UnixNano()),
		CustomerID:        fmt.Sprintf("CUST_%d", rand.Intn(1000)),
		DeliveryStationID: stationID,
		Status:            model.OrderStatusPending,
		Priority:          a.calculatePriority(action),
		CreateTime:        orderTime,
		ReleaseTime:       orderTime.Add(24 * time.Hour),
		Location: model.Location{
			Latitude:  30.0 + rand.Float64(), // 随机生成在某个区域范围内的坐标
			Longitude: 120.0 + rand.Float64(),
			Address:   fmt.Sprintf("测试地址_%d", rand.Intn(1000)),
		},
	}
}

// calculatePriority 计算订单优先级
func (a *TimeSeriesAnalyzer) calculatePriority(action string) int {
	// 根据强化学习的决策计算优先级
	// 这里简化实现，实际应用中需要更复杂的逻辑
	return 3
}

// calculateDistance 计算配送距离
func (a *TimeSeriesAnalyzer) calculateDistance(action string) float64 {
	// 根据强化学习的决策计算距离
	// 这里简化实现，实际应用中需要更复杂的逻辑
	return 5.0
}

// FindPeakHours 找出高峰时段（订单量超过平均数的时段）
func (a *TimeSeriesAnalyzer) FindPeakHours() []int {
	// 预测24小时的订单量
	predictions := make([]float64, 24)
	for i := 0; i < 24; i++ {
		predictions[i] = a.lstmPredictor.Predict(time.Now().Add(time.Duration(i) * time.Hour))
	}
	// 找出订单量超过平均值的时段
	average := 0.0
	for _, count := range predictions {
		average += count
	}
	average /= float64(len(predictions))
	peakHours := make([]int, 0)
	for hour, count := range predictions {
		if count > average {
			peakHours = append(peakHours, hour)
		}
	}
	return peakHours
}

// getPopularAreas 获取热门区域
func (a *TimeSeriesAnalyzer) getPopularAreas(timeSlot time.Time) []string {
	// 使用历史数据分析热门区域
	// 这里简化实现，实际应用中需要更复杂的逻辑
	return []string{"区域A", "区域B", "区域C"}
}

// calculateAverageVolume 计算指定时间段的平均订单量
func (a *TimeSeriesAnalyzer) calculateAverageVolume(t time.Time) float64 {
	prediction := a.lstmPredictor.Predict(t)
	return prediction
}

// AnalyzeSeasonalTrends 分析季节性趋势
func (a *TimeSeriesAnalyzer) AnalyzeSeasonalTrends() map[string]float64 {
	// 预测365天的订单量
	predictions := make([]float64, 365)
	startTime := time.Now()
	// 为每个季节设置基础订单量和季节性因子
	seasonalFactors := map[string]float64{
		"spring": 1.0, // 春季基准
		"summer": 1.5, // 夏季最高
		"autumn": 0.8, // 秋季较低
		"winter": 1.2, // 冬季次高
	}
	// 计算每天的订单量预测
	for i := 0; i < 365; i++ {
		dayTime := startTime.Add(time.Duration(i*24) * time.Hour)
		month := dayTime.Month()
		// 获取季节性因子
		var seasonalFactor float64
		switch {
		case month >= 3 && month <= 5: // 春季 (3-5月)
			seasonalFactor = seasonalFactors["spring"]
		case month >= 6 && month <= 8: // 夏季 (6-8月)
			seasonalFactor = seasonalFactors["summer"]
		case month >= 9 && month <= 11: // 秋季 (9-11月)
			seasonalFactor = seasonalFactors["autumn"]
		default: // 冬季 (12,1,2月)
			seasonalFactor = seasonalFactors["winter"]
		}
		// 基础预测值乘以季节性因子，并添加随机波动
		baseValue := a.lstmPredictor.Predict(dayTime)
		randomFactor := 1.0 + (rand.Float64()*0.2 - 0.1) // ±10%的随机波动
		predictions[i] = baseValue * seasonalFactor * randomFactor
	}
	// 按季节分组计算平均值
	seasonalTrends := make(map[string]float64)
	winterSum, winterCount := 0.0, 0
	springSum, springCount := 0.0, 0
	summerSum, summerCount := 0.0, 0
	autumnSum, autumnCount := 0.0, 0
	for i := 0; i < 365; i++ {
		dayTime := startTime.Add(time.Duration(i*24) * time.Hour)
		month := dayTime.Month()
		value := predictions[i]
		switch {
		case month >= 3 && month <= 5: // 春季
			springSum += value
			springCount++
		case month >= 6 && month <= 8: // 夏季
			summerSum += value
			summerCount++
		case month >= 9 && month <= 11: // 秋季
			autumnSum += value
			autumnCount++
		default: // 冬季
			winterSum += value
			winterCount++
		}
	}
	// 计算每个季节的平均值
	if winterCount > 0 {
		seasonalTrends["winter"] = winterSum / float64(winterCount)
	}
	if springCount > 0 {
		seasonalTrends["spring"] = springSum / float64(springCount)
	}
	if summerCount > 0 {
		seasonalTrends["summer"] = summerSum / float64(summerCount)
	}
	if autumnCount > 0 {
		seasonalTrends["autumn"] = autumnSum / float64(autumnCount)
	}
	return seasonalTrends
}

// PredictOrderCount 预测指定时间段的订单数量
func (a *TimeSeriesAnalyzer) PredictOrderCount(startTime time.Time, duration time.Duration) []float64 {
	hours := int(duration.Hours())
	predictions := make([]float64, hours)

	for i := 0; i < hours; i++ {
		predictions[i] = a.lstmPredictor.Predict(startTime.Add(time.Duration(i) * time.Hour))
	}

	return predictions
}

// PredictOrderVolume 预测指定时间段的订单量
func (a *TimeSeriesAnalyzer) PredictOrderVolume(startTime time.Time, duration time.Duration) []float64 {
	hours := int(duration.Hours())
	volumes := make([]float64, hours)
	for i := 0; i < hours; i++ {
		prediction := a.lstmPredictor.Predict(startTime.Add(time.Duration(i) * time.Hour))
		volumes[i] = prediction * 1.5 // 假设每个订单平均1.5个商品
	}
	return volumes
}

// PredictPeakHours 预测高峰时段
func (a *TimeSeriesAnalyzer) PredictPeakHours(startTime time.Time, duration time.Duration) []int {
	hours := int(duration.Hours())
	predictions := make([]float64, hours)
	peakHours := make([]int, 0)

	// 获取预测值
	for i := 0; i < hours; i++ {
		predictions[i] = a.lstmPredictor.Predict(startTime.Add(time.Duration(i) * time.Hour))
	}

	// 计算平均值
	var sum float64
	for _, p := range predictions {
		sum += p
	}
	avg := sum / float64(len(predictions))

	// 找出高于平均值的时段
	for i, p := range predictions {
		if p > avg*1.2 { // 高于平均值20%认为是高峰
			peakHours = append(peakHours, i)
		}
	}

	return peakHours
}
